#pragma once
#include "MeshDefinition.h"
#include <Eigen/Sparse>
#include <Eigen/Core>

enum class Genus2
{
	genus0,
	genus1,
	highgenus,
	withboundary
};

class ricci
{
public:
	ricci(Mesh &mesh, double stepSize, double Thres);

	void init();
	void calculateradii();
	void calculatePos();




private:
	std::vector<double> currentradius;
	std::vector<double> inversedist;
	std::vector<double> currrentlength;
	std::vector<double> orilength;
	Eigen::VectorXd currentK;
	Eigen::VectorXd goalK;
	double aveK;
	double ballradii = 0;
	Genus2 genusnum;

	Mesh* mesh;
	double stepSize;
	double Thres;
	bool isKvalid = true;

	void currentStatus();
	void delauneyFlip();
	void Flip();
	void calculatelength();
	void calculateballradii();
	OpenMesh::Vec3d calculatePosOnBall(OpenMesh::Vec3d a, OpenMesh::Vec3d b, double la, double lb);

	void checkdelauney();
	void callen();

	double Delta(double a, double b, double c)
	{
		return (std::pow(a, 2) + std::pow(b, 2) + std::pow(c, 2) + 2 * a * b * c - 1);
	}

	double trans(double a, double b, double c, double d, double e)
	{
		return ((a*b + c * d + a * c * e + b * d * e + std::sqrt(Delta(a, d, e)) + std::sqrt(Delta(b, c, e))) / (e*e - 1));
	}



};